home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / networking / amitcp / dialupv3.01.lha / dialup / io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-31  |  9.1 KB  |  336 lines

  1. #include "dialup.h"
  2.  
  3. extern const UBYTE             *prgname;
  4. extern struct IOExtSer        *serialIOReq;
  5. extern struct timerequest    *timereq;
  6. extern BPTR                    repfile;
  7. extern UBYTE                *rxbuffer;
  8. extern LONG                    arg[];
  9.  
  10. BOOL    isend( UBYTE *send );            /* real send with \r, \n and \t remapping, string must be in a bigger buffer */
  11.  
  12. UBYTE *
  13. expectFromSer( UBYTE *expect, USHORT waittime )
  14.     {
  15.     UBYTE *result = NULL;
  16.     ULONG WaitMask, timebit, serbit, wres;
  17.  
  18.     WaitMask = 0;
  19.  
  20.     if ( waittime )
  21.         {
  22.         if ( arg[A_VERBOSE] && !expect ) msg("waiting %ld seconds\n", expect, waittime);
  23.         timebit = 1L << timereq->tr_node.io_Message.mn_ReplyPort->mp_SigBit;
  24.         SetSignal(0L, timebit);
  25.         WaitMask |= SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | timebit;
  26.         timereq->tr_node.io_Command = TR_ADDREQUEST;
  27.         timereq->tr_time.tv_secs    = waittime;
  28.         timereq->tr_time.tv_micro    = 0;
  29.         SendIO((struct IORequest *)timereq);
  30.         if ( !expect )
  31.             {
  32.             while ( ! ( (wres = Wait(WaitMask)) & WaitMask ) ); /* Wait for the timeout, no string expected! */
  33.             if ( wres & timebit ) { *rxbuffer = '\0'; result = rxbuffer; };
  34.             };
  35.         };
  36.  
  37.     if ( expect )
  38.         {
  39.         UBYTE *wptrb;
  40.         UBYTE *repptr;
  41.  
  42.         UBYTE mbuf[MAXMATCHSTRING * 25];
  43.         UBYTE *msa[MAXMATCHSTRING];
  44.  
  45.         if ( strlen(expect) > sizeof(mbuf) )
  46.             {
  47.             msg("expectFromSer: expectstring to long!");
  48.             _FAIL_;
  49.             };
  50.  
  51.         if ( arg[A_VERBOSE] ) msg("expecting %s for %ld seconds\n", expect, waittime);
  52.  
  53.         buildMatchStringArray(expect, mbuf, msa);
  54.  
  55.         serbit =  1L << serialIOReq->IOSer.io_Message.mn_ReplyPort->mp_SigBit;
  56.         SetSignal(0L, serbit);
  57.         WaitMask |= SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | serbit;
  58.         wptrb = repptr = rxbuffer;
  59.         wres = 0;
  60.         do    {
  61.             UBYTE *spt;    
  62.  
  63.             serialIOReq->IOSer.io_Command  = SDCMD_QUERY;
  64.             DoIO((struct IORequest *)serialIOReq);
  65.             serialIOReq->IOSer.io_Command  = CMD_READ;
  66.             serialIOReq->IOSer.io_Data       = (APTR)wptrb;
  67.             /* while there are chars on the serial, set and get them (upto bufsize): */
  68.             if ( ( serialIOReq->IOSer.io_Length = min(serialIOReq->IOSer.io_Actual, RXBUFSIZE - (wptrb - rxbuffer)) ) > 0 )
  69.                 {
  70.                 DoIO((struct IORequest *)serialIOReq);
  71.                 wptrb += serialIOReq->IOSer.io_Actual;
  72.                 continue;
  73.                 }
  74.             *wptrb = '\0'; /* Terminate received string and replace any received \0's with spaces, to make a stringsearch possible: */
  75.             while ( spt = memchr(repptr, '\0', wptrb - repptr ) ) memmove(spt, spt + 1, wptrb-- - spt);
  76.  
  77.             /* Report the conversation. The modem echos commands sent to it: */
  78.             if ( repfile && wptrb > repptr ) { Write( repfile, repptr, wptrb - repptr); repptr = wptrb; };
  79.  
  80.             /* check whether one of the matchstrings is in the receive buffer. Stop and return it if so. */
  81.             if ( result = matchString(rxbuffer, msa) ) break;
  82.  
  83.             /* wait for one char, break or timeout: */
  84.             serialIOReq->IOSer.io_Length = 1;
  85.             SendIO((struct IORequest *)serialIOReq);
  86.             while ( ! ( (wres = Wait(WaitMask)) & WaitMask ) );
  87.             if ( wres & serbit || wres & SIGBREAKF_CTRL_F )
  88.                 {
  89.                 if(CheckIO((struct IORequest *)serialIOReq) )    /* If request is complete... */
  90.                     {
  91.                     WaitIO((struct IORequest *)serialIOReq);    /* clean up and remove reply */
  92.                     wptrb += serialIOReq->IOSer.io_Actual;
  93.                     *wptrb = '\0';                                /* Terminate received string */
  94.                     }
  95.                 }
  96.             else if ( (wres & timebit) )
  97.                 {
  98.                 UBYTE *cbptr;
  99.                 UBYTE *rbptr;
  100.                 UBYTE ccnt;
  101.                 for(rbptr = rxbuffer, cbptr = wptrb + 1; ( rbptr < wptrb ) && ((cbptr + 20) < (rxbuffer + RXBUFSIZE)); rbptr += 8)
  102.                     {
  103.                     cbptr += sprintf(cbptr, "%08lX %08lX  ", *(ULONG *)rbptr, *(ULONG *)(rbptr + 4) );
  104.                     for(ccnt = 0; rbptr[ccnt] && ccnt < 8; ccnt++)
  105.                         if ( strchr("\n\r\t", rbptr[ccnt] ) ) rbptr[ccnt] = 1;
  106.                     cbptr += sprintf(cbptr, "%-.4s ", rbptr);
  107.                     if (rbptr + 4 < wptrb) cbptr += sprintf(cbptr, "%-.4s\n", rbptr + 4 );
  108.                     };
  109.                 msg("TIMEOUT, after waiting %ld secs for:\n'%s'\nReceived:\n%s", waittime, expect, wptrb + 1);
  110.                 }
  111.             }
  112.         while ( ! ( wres & ( SIGBREAKF_CTRL_C | timebit ) ) );
  113.  
  114.         if ( wres & SIGBREAKF_CTRL_C ) { strcpy(wptrb, BREAKSTR); wptrb += sizeof(BREAKSTR); };
  115.  
  116.         if( !CheckIO((struct IORequest *)serialIOReq) ) /* If request is complete... */
  117.             {
  118.             AbortIO((struct IORequest *)serialIOReq);  /* Ask device to abort request, if pending */
  119.             WaitIO((struct IORequest *)serialIOReq);   /* clean up and remove reply */
  120.             if ( SetSignal(0, 0) & serbit ) SetSignal(0, serbit );
  121.             }
  122.  
  123.         if ( repfile && (wptrb > repptr) )
  124.             {
  125.             Write( repfile, repptr, wptrb - repptr); /* Report the conversation, cause normaly modem echos commands sent to it. */
  126.             repptr = wptrb;
  127.             };
  128.         };
  129.  
  130.     if( waittime && !CheckIO((struct IORequest *)timereq) ) /* Abort any pending timer requests */
  131.         {
  132.         AbortIO((struct IORequest *)timereq);
  133.         WaitIO((struct IORequest *)timereq);
  134.         if ( SetSignal(0, 0) & timebit ) SetSignal(0, timebit );
  135.         }
  136.  
  137.     return( result );
  138.     }
  139.  
  140. #define SCRATCHBUFSIZE 1000
  141.  
  142. BOOL
  143. sendLine( UBYTE *send )
  144.     {
  145.     UBYTE buf[SCRATCHBUFSIZE];
  146.  
  147.     if ( strlen(send) >= SCRATCHBUFSIZE - 1 ) _FAIL_
  148.     sprintf(buf, "%s\r", send);
  149.     return(isend(buf));
  150.     }
  151.  
  152. UBYTE *
  153. sendEx( UBYTE *send , UBYTE *expect, USHORT waittime )
  154.     {
  155.     UBYTE buf[SCRATCHBUFSIZE];
  156.  
  157.     if ( strlen(send) >= SCRATCHBUFSIZE - 1 ) _FAIL_
  158.     sprintf(buf, "%s\r", send);
  159.     if ( !isend(buf) ) return(FALSE);
  160.     return( expectFromSer(expect, waittime) );
  161.     }
  162.  
  163. UBYTE *
  164. exSend( UBYTE *expect, USHORT waittime, UBYTE *send )
  165.     {
  166.     UBYTE *rxbufp;
  167.  
  168.     if ( strlen(send) >= SCRATCHBUFSIZE - 1 ) _FAIL_
  169.     if (rxbufp = expectFromSer(expect, waittime) )
  170.         {
  171.         UBYTE buf[SCRATCHBUFSIZE];
  172.         sprintf(buf, "%s\r", send);
  173.         if ( !isend(buf) ) return(NULL);
  174.         }
  175.     return(rxbufp);
  176.     }
  177.  
  178. BOOL
  179. sendToSer( UBYTE *send )
  180.     {
  181.     UBYTE buf[SCRATCHBUFSIZE];
  182.  
  183.     if ( strlen(send) >= SCRATCHBUFSIZE ) _FAIL_
  184.     strcpy(buf, send);    /* copying string to be able modify it */
  185.     return(isend(send));
  186.     }
  187.  
  188. BOOL
  189. isend( UBYTE *send )        /* this gets only called by sendEx(), exSend() and sendToSer() */
  190.     {
  191.     UBYTE *mptr = send;
  192.  
  193.     while ( *mptr != '\0' )
  194.         {
  195.         if ( *mptr++ == '\\' )
  196.             {
  197.             if      ( *mptr == 'r' ) *mptr = '\r';
  198.             else if ( *mptr == 'n' ) *mptr = '\n';
  199.             else if ( *mptr == 't' ) *mptr = '\t';
  200.             memmove(mptr - 1, mptr, strlen(mptr) + 1);
  201.             };
  202.         };
  203.  
  204.     if ( arg[A_VERBOSE] ) msg("Sending %s\n", send);
  205.  
  206.     Delay(2);
  207.     serialIOReq->IOSer.io_Command  = CMD_WRITE;
  208.     serialIOReq->IOSer.io_Data       = (APTR)send;
  209.     serialIOReq->IOSer.io_Length   = strlen(send);
  210.     if ( DoIO( (struct IORequest *)serialIOReq ) )
  211.         {
  212.         msg("failed to write to serial line\n");
  213.         return(FALSE);
  214.         }
  215.     return(TRUE);
  216.     }
  217.  
  218.  
  219. /*
  220. ** The next lines are stolen from the slip.device (Rhialto Seibert, Comodore)
  221. **
  222. ** ReadConfig
  223. **
  224. ** Attempt to read in and parse the driver's configuration file.
  225. **
  226. ** The files are named by ENV:SANA2/slip0.config where X is the decimal
  227. ** representation of the device's unit number.
  228. **
  229. */
  230.  
  231. #define LINEBUFFSIZE 1024
  232. #define NUMARGS 10
  233.  
  234. BOOL ReadConfig(STRPTR sanacfgfile, USHORT sanaUnit, struct SP *sp)
  235.     {
  236.     UBYTE *linebuff;
  237.     UBYTE buff[80] = "ENV:SANA2/";
  238.     UBYTE *termchar;
  239.     struct RDArgs *rdargs;
  240.     BPTR ConfigFile;
  241.     LONG arg[NUMARGS];
  242.     BOOL status = FALSE;
  243.     ULONG linenum=0;
  244.     UWORD i;
  245.  
  246.     sprintf(buff + ( strchr(sanacfgfile, ':') ? 0 : strlen(buff) ), sanacfgfile, (ULONG)sanaUnit);
  247.     if(ConfigFile = Open(buff,MODE_OLDFILE))
  248.         {
  249.         if(linebuff = AllocMem(LINEBUFFSIZE, MEMF_CLEAR|MEMF_PUBLIC))
  250.             {
  251.             if(rdargs = AllocDosObject(DOS_RDARGS, NULL))
  252.                 {
  253.                 while( FGets( ConfigFile, linebuff, LINEBUFFSIZE - 1) )
  254.                     {
  255.                     linenum++;
  256.                     if(linebuff[0] == '#') /* Skip comment lines */ continue;
  257.  
  258.                     rdargs->RDA_Source.CS_Buffer = linebuff;
  259.                     rdargs->RDA_Source.CS_Length = LINEBUFFSIZE;
  260.                     rdargs->RDA_Source.CS_CurChr = 0;
  261.  
  262.                     /* ReadArgs() requires that the line be null-terminated or funny things happen. */
  263.                     termchar = (UBYTE *) linebuff + strlen(linebuff);
  264.                     *termchar = '\n';
  265.                     termchar++;
  266.                     *termchar = 0;
  267.  
  268.                     for(i = 0; i < NUMARGS ; i++) arg[i] = NULL;
  269.                     if( ReadArgs( "SERNAME/A,SERUNIT/A/N,SERBAUD/A/N,IPSTR/A,CD=CARRIERDETECT/S,7WIRE/S,EOFMODE/S,MTU/K/N,THEREST/F", arg, rdargs ) )
  270.                         {
  271.                         status = TRUE;
  272.                         strcpy( sp->serDevName,    (UBYTE *)arg[0] );
  273.                         sp->serUnit            = *((ULONG *)arg[1]);
  274.                         sp->serBaudRate        = *((ULONG *)arg[2]);
  275.                         sp->listen2CD        =             arg[4] ? TRUE : FALSE;
  276.                         sp->serHWHS            =             arg[5] ? TRUE : FALSE;
  277.                         FreeArgs(rdargs);
  278.                         break;
  279.                         }
  280.                     else
  281.                         {
  282.                         msg("Error parsing sana arguments in %s", buff);
  283.                         break;
  284.                         }
  285.                     }
  286.                 FreeDosObject(DOS_RDARGS, rdargs);
  287.                 }
  288.             FreeMem(linebuff, LINEBUFFSIZE);
  289.             }
  290.         Close(ConfigFile);
  291.         }
  292.     return(status);
  293.     }
  294.  
  295.  
  296. VOID
  297. msg(UBYTE *msg, ...)
  298.     {
  299.     extern BPTR    mystderr;
  300.     va_list args;
  301.  
  302.     va_start(args, msg);
  303.      if(mystderr)
  304.         {
  305.         VFPrintf(mystderr, msg, args);
  306.         VFPrintf(mystderr, "\n", NULL);
  307.         }
  308.     else
  309.         {
  310.         struct Library *IntuitionBase;
  311.         static struct EasyStruct es;
  312.  
  313.         if(IntuitionBase = OpenLibrary("intuition.library", 37))
  314.             {
  315.             es.es_StructSize=sizeof(struct EasyStruct);
  316.             es.es_Flags = 0;
  317.             es.es_Title = prgname;
  318.             es.es_TextFormat = msg;
  319.             es.es_GadgetFormat = "OK";
  320.             EasyRequestArgs(NULL, &es, 0, args);
  321.             CloseLibrary(IntuitionBase);
  322.             };
  323.         }; 
  324.     va_end(args);
  325.     }
  326.  
  327. BOOL
  328. carrier()
  329.     {
  330.     /* modem online? */
  331.     serialIOReq->IOSer.io_Command  = SDCMD_QUERY;
  332.     if ( DoIO((struct IORequest *)serialIOReq) ) msg("Error: Query serial line.");
  333.     return( (BOOL)( (serialIOReq->io_Status & ( 1 << 5 ) ) == 0 ) );
  334.     }
  335.  
  336.